#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
语言识别程序 - 支持多种检测方法
包含在线API和本地库两种方式
"""

import requests
import json
from typing import Dict, List, Optional, Tuple
import re

# 本地库导入（需要安装）
try:
    from langdetect import detect, detect_langs
    from langdetect.lang_detect_exception import LangDetectException
    LANGDETECT_AVAILABLE = True
except ImportError:
    LANGDETECT_AVAILABLE = False

try:
    import langid
    LANGID_AVAILABLE = True
except ImportError:
    LANGID_AVAILABLE = False

class LanguageDetector:
    """
    语言检测器类，支持多种检测方法
    """
    
    def __init__(self):
        self.language_names = {
            'zh': '中文', 'zh-cn': '中文（简体）', 'zh-tw': '中文（繁体）',
            'en': 'English', 'es': 'Español', 'fr': 'Français',
            'de': 'Deutsch', 'it': 'Italiano', 'pt': 'Português',
            'ru': 'Русский', 'ja': '日本語', 'ko': '한국어',
            'ar': 'العربية', 'hi': 'हिंदी', 'th': 'ภาษาไทย',
            'vi': 'Tiếng Việt', 'id': 'Indonesia', 'ms': 'Malay',
            'tr': 'Türkçe', 'nl': 'Nederlands', 'sv': 'Svenska',
            'da': 'Dansk', 'no': 'Norsk', 'fi': 'Suomi',
            'pl': 'Polski', 'cs': 'Čeština', 'sk': 'Slovenčina',
            'hu': 'Magyar', 'ro': 'Română', 'bg': 'Български',
            'hr': 'Hrvatski', 'sr': 'Српски', 'sl': 'Slovenščina',
            'et': 'Eesti', 'lv': 'Latviešu', 'lt': 'Lietuvių',
            'uk': 'Українська', 'be': 'Беларуская', 'mk': 'Македонски',
            'el': 'Ελληνικά', 'he': 'עברית', 'fa': 'فارسی',
            'ur': 'اردو', 'bn': 'বাংলা', 'ta': 'தமிழ்',
            'te': 'తెలుగు', 'ml': 'മലയാളം', 'kn': 'ಕನ್ನಡ',
            'gu': 'ગુજરાતી', 'pa': 'ਪੰਜਾਬੀ', 'mr': 'मराठी',
            'ne': 'नेपाली', 'si': 'සිංහල', 'my': 'မြန်မာ',
            'km': 'ខ្មែរ', 'lo': 'ລາວ', 'ka': 'ქართული',
            'am': 'አማርኛ', 'sw': 'Kiswahili', 'zu': 'isiZulu',
            'af': 'Afrikaans', 'sq': 'Shqip', 'eu': 'Euskera',
            'ca': 'Català', 'cy': 'Cymraeg', 'ga': 'Gaeilge',
            'is': 'Íslenska', 'mt': 'Malti', 'unknown': '未知语言'
        }
    
    def detect_with_google_api(self, text: str, api_key: str) -> Dict:
        """
        使用Google Cloud Translation API检测语言
        需要API密钥
        """
        url = f"https://translation.googleapis.com/language/translate/v2/detect"
        
        params = {
            'key': api_key,
            'q': text
        }
        
        try:
            response = requests.post(url, data=params, timeout=10)
            response.raise_for_status()
            
            result = response.json()
            detection = result['data']['detections'][0][0]
            
            return {
                'method': 'Google API',
                'language': detection['language'],
                'language_name': self.language_names.get(detection['language'], detection['language']),
                'confidence': detection['confidence'],
                'success': True,
                'error': None
            }
            
        except Exception as e:
            return {
                'method': 'Google API',
                'language': None,
                'language_name': None,
                'confidence': 0,
                'success': False,
                'error': str(e)
            }
    
    def detect_with_azure_api(self, text: str, api_key: str, region: str = 'eastus') -> Dict:
        """
        使用Azure Translator API检测语言
        需要API密钥和区域
        """
        url = f"https://api.cognitive.microsofttranslator.com/detect"
        
        headers = {
            'Ocp-Apim-Subscription-Key': api_key,
            'Ocp-Apim-Subscription-Region': region,
            'Content-Type': 'application/json'
        }
        
        body = [{'text': text}]
        
        try:
            response = requests.post(url, headers=headers, json=body, timeout=10)
            response.raise_for_status()
            
            result = response.json()[0]
            
            return {
                'method': 'Azure API',
                'language': result['language'],
                'language_name': self.language_names.get(result['language'], result['language']),
                'confidence': result['score'],
                'success': True,
                'error': None
            }
            
        except Exception as e:
            return {
                'method': 'Azure API',
                'language': None,
                'language_name': None,
                'confidence': 0,
                'success': False,
                'error': str(e)
            }
    
    def detect_with_libre_translate(self, text: str, api_url: str = "https://libretranslate.de") -> Dict:
        """
        使用LibreTranslate API检测语言（免费）
        """
        url = f"{api_url}/detect"
        
        data = {
            'q': text
        }
        
        try:
            response = requests.post(url, data=data, timeout=10)
            response.raise_for_status()
            
            result = response.json()
            
            return {
                'method': 'LibreTranslate',
                'language': result['language'],
                'language_name': self.language_names.get(result['language'], result['language']),
                'confidence': result['confidence'],
                'success': True,
                'error': None
            }
            
        except Exception as e:
            return {
                'method': 'LibreTranslate',
                'language': None,
                'language_name': None,
                'confidence': 0,
                'success': False,
                'error': str(e)
            }
    
    def detect_with_langdetect(self, text: str) -> Dict:
        """
        使用langdetect库检测语言（本地）
        """
        if not LANGDETECT_AVAILABLE:
            return {
                'method': 'langdetect',
                'language': None,
                'language_name': None,
                'confidence': 0,
                'success': False,
                'error': 'langdetect library not installed. Run: pip install langdetect'
            }
        
        try:
            # 检测语言
            language = detect(text)
            
            # 获取详细信息（包含置信度）
            lang_probs = detect_langs(text)
            confidence = lang_probs[0].prob if lang_probs else 0
            
            return {
                'method': 'langdetect',
                'language': language,
                'language_name': self.language_names.get(language, language),
                'confidence': confidence,
                'success': True,
                'error': None
            }
            
        except LangDetectException as e:
            return {
                'method': 'langdetect',
                'language': None,
                'language_name': None,
                'confidence': 0,
                'success': False,
                'error': str(e)
            }
    
    def detect_with_langid(self, text: str) -> Dict:
        """
        使用langid库检测语言（本地）
        """
        if not LANGID_AVAILABLE:
            return {
                'method': 'langid',
                'language': None,
                'language_name': None,
                'confidence': 0,
                'success': False,
                'error': 'langid library not installed. Run: pip install langid'
            }
        
        try:
            language, confidence = langid.classify(text)
            
            return {
                'method': 'langid',
                'language': language,
                'language_name': self.language_names.get(language, language),
                'confidence': confidence,
                'success': True,
                'error': None
            }
            
        except Exception as e:
            return {
                'method': 'langid',
                'language': None,
                'language_name': None,
                'confidence': 0,
                'success': False,
                'error': str(e)
            }
    
    def detect_with_simple_rules(self, text: str) -> Dict:
        """
        使用简单规则检测语言（基于字符特征）
        支持更多语言的Unicode字符范围检测
        """
        try:
            total_chars = len(text)
            if total_chars == 0:
                return {
                    'method': 'Simple Rules',
                    'language': 'unknown',
                    'language_name': '未知语言',
                    'confidence': 0,
                    'success': True,
                    'error': None
                }
            
            # 扩展的字符范围检测规则
            char_patterns = {
                # 东亚语言
                'zh': r'[\u4e00-\u9fff]',                    # 中文汉字
                'ja': r'[\u3040-\u309f\u30a0-\u30ff]',      # 日文平假名片假名
                'ko': r'[\uac00-\ud7af]',                    # 韩文
                
                # 阿拉伯语系
                'ar': r'[\u0600-\u06ff]',                    # 阿拉伯文
                'fa': r'[\u0600-\u06ff]',                    # 波斯文（与阿拉伯文共用字符）
                'ur': r'[\u0600-\u06ff]',                    # 乌尔都文
                
                # 西里尔字母语系
                'ru': r'[\u0400-\u04ff]',                    # 俄文
                'uk': r'[\u0400-\u04ff]',                    # 乌克兰文
                'bg': r'[\u0400-\u04ff]',                    # 保加利亚文
                'sr': r'[\u0400-\u04ff]',                    # 塞尔维亚文
                'mk': r'[\u0400-\u04ff]',                    # 马其顿文
                'be': r'[\u0400-\u04ff]',                    # 白俄罗斯文
                
                # 南亚语言
                'hi': r'[\u0900-\u097f]',                    # 印地文
                'bn': r'[\u0980-\u09ff]',                    # 孟加拉文
                'ta': r'[\u0b80-\u0bff]',                    # 泰米尔文
                'te': r'[\u0c00-\u0c7f]',                    # 泰卢固文
                'ml': r'[\u0d00-\u0d7f]',                    # 马拉雅拉姆文
                'kn': r'[\u0c80-\u0cff]',                    # 卡纳达文
                'gu': r'[\u0a80-\u0aff]',                    # 古吉拉特文
                'pa': r'[\u0a00-\u0a7f]',                    # 旁遮普文
                'mr': r'[\u0900-\u097f]',                    # 马拉地文
                'ne': r'[\u0900-\u097f]',                    # 尼泊尔文
                'si': r'[\u0d80-\u0dff]',                    # 僧伽罗文
                
                # 东南亚语言
                'th': r'[\u0e00-\u0e7f]',                    # 泰文
                'my': r'[\u1000-\u109f]',                    # 缅甸文
                'km': r'[\u1780-\u17ff]',                    # 高棉文
                'lo': r'[\u0e80-\u0eff]',                    # 老挝文
                'vi': r'[\u1ea0-\u1ef9]',                    # 越南文特殊字符
                
                # 其他语言
                'am': r'[\u1200-\u137f]',                    # 阿姆哈拉文
                'ka': r'[\u10a0-\u10ff]',                    # 格鲁吉亚文
                'he': r'[\u0590-\u05ff]',                    # 希伯来文
                'el': r'[\u0370-\u03ff]',                    # 希腊文
            }
            
            # 计算各语言字符占比
            ratios = {}
            for lang, pattern in char_patterns.items():
                matches = len(re.findall(pattern, text))
                if matches > 0:
                    ratios[lang] = matches / total_chars
            
            # 如果没有找到特殊字符，检查是否包含拉丁字符
            if not ratios:
                latin_chars = len(re.findall(r'[a-zA-Z]', text))
                if latin_chars > 0:
                    # 简单的拉丁语言区分（基于常见词汇特征）
                    text_lower = text.lower()
                    
                    # 英语特征词
                    if any(word in text_lower for word in ['the', 'and', 'is', 'in', 'to', 'of', 'a']):
                        return self._create_result('en', 0.7)
                    # 德语特征词
                    elif any(word in text_lower for word in ['der', 'die', 'das', 'und', 'ist', 'mit']):
                        return self._create_result('de', 0.6)
                    # 法语特征词
                    elif any(word in text_lower for word in ['le', 'la', 'les', 'et', 'est', 'de', 'du']):
                        return self._create_result('fr', 0.6)
                    # 西班牙语特征词
                    elif any(word in text_lower for word in ['el', 'la', 'los', 'las', 'y', 'es', 'de']):
                        return self._create_result('es', 0.6)
                    # 意大利语特征词
                    elif any(word in text_lower for word in ['il', 'la', 'gli', 'le', 'e', 'è', 'di']):
                        return self._create_result('it', 0.6)
                    # 葡萄牙语特征词
                    elif any(word in text_lower for word in ['o', 'a', 'os', 'as', 'e', 'é', 'de']):
                        return self._create_result('pt', 0.6)
                    else:
                        # 默认认为是英语
                        return self._create_result('en', 0.4)
                else:
                    # 没有拉丁字符，可能是数字或符号
                    return self._create_result('unknown', 0)
            
            # 找到最高占比的语言
            max_lang = max(ratios, key=ratios.get)
            max_ratio = ratios[max_lang]
            
            # 对于某些共用字符的语言，需要进一步区分
            if max_lang in ['ar', 'fa', 'ur'] and max_ratio > 0.5:
                # 阿拉伯语系进一步区分（简化版）
                text_lower = text.lower()
                if any(char in text for char in ['ی', 'گ', 'چ', 'پ']):  # 波斯文特有字符
                    max_lang = 'fa'
                elif any(char in text for char in ['ں', 'ے', 'ھ']):  # 乌尔都文特有字符
                    max_lang = 'ur'
                # 否则保持为阿拉伯文
            
            return self._create_result(max_lang, max_ratio)
            
        except Exception as e:
            return {
                'method': 'Simple Rules',
                'language': None,
                'language_name': None,
                'confidence': 0,
                'success': False,
                'error': str(e)
            }
    
    def _create_result(self, language: str, confidence: float) -> Dict:
        """创建检测结果的辅助方法"""
        return {
            'method': 'Simple Rules',
            'language': language,
            'language_name': self.language_names.get(language, language),
            'confidence': confidence,
            'success': True,
            'error': None
        }
    
    def detect_all_methods(self, text: str, google_api_key: str = None, 
                          azure_api_key: str = None, azure_region: str = 'eastus') -> List[Dict]:
        """
        使用所有可用方法检测语言
        """
        results = []
        
        # 本地方法（快速）
        results.append(self.detect_with_simple_rules(text))
        results.append(self.detect_with_langdetect(text))
        results.append(self.detect_with_langid(text))
        
        # 在线API方法（需要密钥）
        if google_api_key:
            results.append(self.detect_with_google_api(text, google_api_key))
        
        if azure_api_key:
            results.append(self.detect_with_azure_api(text, azure_api_key, azure_region))
        
        # 免费在线API
        results.append(self.detect_with_libre_translate(text))
        
        return results
    
    def get_best_result(self, results: List[Dict]) -> Dict:
        """
        从多个检测结果中选择最佳结果
        """
        # 过滤成功的结果
        successful_results = [r for r in results if r['success']]
        
        if not successful_results:
            return {
                'method': 'Best Result',
                'language': 'unknown',
                'language_name': '未知语言',
                'confidence': 0,
                'success': False,
                'error': 'All detection methods failed'
            }
        
        # 按置信度排序，选择最高的
        best_result = max(successful_results, key=lambda x: x['confidence'])
        best_result['method'] = f"Best Result ({best_result['method']})"
        
        return best_result

def main():
    """
    主函数 - 演示语言检测功能
    """
    detector = LanguageDetector()
    
    # 测试文本
    test_texts = [
        "🇰🇷 CryptoKorean 크립토코리안🇰🇷",
        "Digital mine🇰🇷🇰🇷🇰🇷",
        "Bitgame 공식 커뮤니티",
        "WOWMAX.EXCHANGE(한국어 공식 커뮤니티)",
        "Btok官方交流16群",
        "8V.com 中文官方交流群",
        "CEO （SGLOBAL官方中文交流群）",
        "Dies ist ein deutscher Testtext für die Spracherkennung.",
        "Este es un texto de prueba en español para detección de idioma.",
        "Questo è un testo di prova in italiano per il rilevamento della lingua."
    ]
    
    print("=== 语言检测程序演示 ===\n")
    
    for i, text in enumerate(test_texts, 1):
        print(f"测试文本 {i}: {text[:50]}{'...' if len(text) > 50 else ''}")
        print("-" * 80)
        
        # 使用所有本地方法检测
        results = [
            # detector.detect_with_simple_rules(text),
            detector.detect_with_langdetect(text),
            detector.detect_with_langid(text),
            # detector.detect_with_libre_translate(text)
        ]
        
        # 显示结果
        for result in results:
            if result['success']:
                print(f"{result['method']:15} | {result['language']:5} | {result['language_name']:15} | 置信度: {result['confidence']:.3f}")
            else:
                print(f"{result['method']:15} | 失败: {result['error']}")
        
        # 获取最佳结果
        best = detector.get_best_result(results)
        if best['success']:
            print(f"{'最佳结果':15} | {best['language']:5} | {best['language_name']:15} | 置信度: {best['confidence']:.3f}")
        
        print("\n")

if __name__ == "__main__":
    main()
